package com.ts.opengl.simpleDraw

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.opengl.GLES20
import android.opengl.GLES20.GL_COLOR_ATTACHMENT0
import android.opengl.GLES20.GL_LINEAR
import android.opengl.GLES20.GL_LINEAR_MIPMAP_LINEAR
import android.opengl.GLES20.GL_NEAREST
import android.opengl.GLES20.GL_NONE
import android.opengl.GLES20.GL_TEXTURE0
import android.opengl.GLES20.GL_TEXTURE_2D
import android.opengl.GLES20.GL_TEXTURE_MAG_FILTER
import android.opengl.GLES20.GL_TEXTURE_MIN_FILTER
import android.opengl.GLES20.GL_UNPACK_ALIGNMENT
import android.opengl.GLES20.GL_UNSIGNED_INT
import android.opengl.GLES20.GL_UNSIGNED_SHORT
import android.opengl.GLES20.glActiveTexture
import android.opengl.GLES20.glBindFramebuffer
import android.opengl.GLES20.glBindTexture
import android.opengl.GLES20.glGetError
import android.opengl.GLES20.glPixelStorei
import android.opengl.GLES20.glTexParameteri
import android.opengl.GLES20.glUseProgram
import android.opengl.GLES30
import android.opengl.GLES30.glBindVertexArray
import android.util.Log
import com.ts.audiocamera.R
import java.nio.ByteBuffer
import java.nio.ByteOrder
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

abstract class FboBaseRender(var context: Context):BaseRender(context) {



    fun createFbo(width: Int,height: Int){

        GLES30.glGenTextures(textures.size,textures,0)
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,textures[0])
        //设置纹理过滤参数，GL_TEXTURE_MIN_FILTER代表纹理缩写的情况，GL_LINEAR_MIPMAP_LINEAR代表缩小时使用三线性过滤的方式，至于过滤方式以后再详解
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        //GL_TEXTURE_MAG_FILTER代表纹理放大，GL_LINEAR代表双线性过滤
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

        GLES30.glGenFramebuffers(frameBuffers.size, frameBuffers,0)



        Log.e(TAG,bitmap?.width.toString()+"---长度--"+bitmap?.height.toString())
        GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D,0,GLES30.GL_RGB,
            width, height,0,GLES30.GL_RGB,
            GLES30.GL_UNSIGNED_SHORT_5_6_5,null)



        glBindFramebuffer(GLES30.GL_FRAMEBUFFER,frameBuffers[0])

        GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
            GLES30.GL_TEXTURE_2D,textures[0],0)
        val status = GLES30.glCheckFramebufferStatus(GLES30.GL_FRAMEBUFFER)

        if (status != GLES30.GL_FRAMEBUFFER_COMPLETE) {
            throw RuntimeException("Failed to create texture.")
        }

        bitmap?.recycle()
        glBindTexture(GL_TEXTURE_2D, 0)
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0)

    }
    val bitmap1:Bitmap by lazy {
        BitmapFactory.decodeResource(conext.resources, R.drawable.cdemo)
    };

    abstract fun getFboVertex():Int
    abstract fun getFboFragment():Int
    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        super.onSurfaceCreated(gl, config)
        programfbo=openglUtil.createProgram(context,getFboVertex(),getFboFragment())

//        createFbo();

        bitmap?.height?.let { bitmap?.width?.let { it1 -> createFbo(it1, it) } };

    }

//    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
//        super.onSurfaceChanged(gl, width, height)
//
//    }


    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {

        super.onSurfaceChanged(gl, width, height)
        GLES30.glViewport(0, 0, bitmap1.width, bitmap1.height)
    }



    private fun useFbo(width: Int, height: Int) {

        GLES30.glGenFramebuffers(1, frameBuffers, 0)

        GLES30.glGenTextures(1, textures, 0)


        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textures[0])


        //纹理过滤
        GLES30.glTexParameteri(
            GLES30.GL_TEXTURE_2D,
            GLES30.GL_TEXTURE_MIN_FILTER,
            GLES30.GL_NEAREST
        )
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR)

        GLES30.glTexImage2D(
            GLES30.GL_TEXTURE_2D,
            0,
            GLES30.GL_RGB,
            width,
            height,
            0,
            GLES30.GL_RGB,
            GLES30.GL_UNSIGNED_SHORT_5_6_5,
            null
        )

        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, frameBuffers[0])
        GLES30.glFramebufferTexture2D(
            GLES30.GL_FRAMEBUFFER,
            GLES30.GL_COLOR_ATTACHMENT0,
            GLES30.GL_TEXTURE_2D,
            textures[0],
            0
        )

        val status = GLES30.glCheckFramebufferStatus(GLES30.GL_FRAMEBUFFER)
        if (status != GLES30.GL_FRAMEBUFFER_COMPLETE) {
            throw RuntimeException("Failed to create texture.")
        }

        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0)
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0)
    }


    var programfbo=0;

    private  val TAG = "FboBaseRender"

    override fun onDrawFrame(gl: GL10?) {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)
        Log.e(TAG,"宽度"+width+"----"+height)
        GLES30.glViewport(0, 0, bitmap1.width, bitmap1.height)
        Log.e(TAG,glGetError().toString()+"")
        glUseProgram(programfbo)
        glBindFramebuffer(GLES30.GL_FRAMEBUFFER,0)
        glBindFramebuffer(GLES30.GL_FRAMEBUFFER,frameBuffers[0])

        glBindVertexArray(0)
        Log.e(TAG,glGetError().toString()+"")
        glBindTexture(GLES30.GL_TEXTURE_2D,0)
        glBindTexture(GLES30.GL_TEXTURE_2D,imagetextture[0])
        GLES30.glBindVertexArray(vao[1])
//        glActiveTexture(GL_TEXTURE0);


        Log.e(TAG,glGetError().toString()+"")
        GLES30.glDrawElements(GLES30.GL_TRIANGLE_STRIP,6, GL_UNSIGNED_INT,0)
        Log.e(TAG,glGetError().toString()+"")
        glBindTexture(GLES30.GL_TEXTURE_2D,GL_NONE)
        glBindFramebuffer(GLES30.GL_FRAMEBUFFER,GL_NONE)/**/

       var bitmap2= readBufferPixelToBitmap(bitmap1.width,bitmap1.height)
        Log.e(TAG,bitmap2.width.toString()+"--宽度-"+bitmap2.height.toString())
        glBindVertexArray(GL_NONE)
        GLES30.glViewport(0, 0, width, height)
        super.onDrawFrame(gl)
    }


    fun readBufferPixelToBitmap(width: Int, height: Int): Bitmap {
        val buf = ByteBuffer.allocateDirect(width * height * 4)
        buf.order(ByteOrder.LITTLE_ENDIAN)
        GLES30.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buf)
        buf.rewind()
        val bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        bmp.copyPixelsFromBuffer(buf)
        return bmp
    }
}